package services

import (
	"encoding/json"
	"fmt"
	"gitlab.yunzhen-data.com/C-Chain/titan/bytesutils"
	"io/ioutil"
	"os"
	"os/exec"
)

// DeployService 框架相关
type DeployService struct {
}

func (receiver *DeployService) Inject() string {
	return bytesutils.EmptyString
}

func NewDeployService() *DeployService {
	return &DeployService{}
}

// 逻辑相关
type operatorConfig struct {
	App struct {
		MeshClient struct {
			AppCode   string `json:"app-code"`
			AppPort   string `json:"app-port"`
			Namespace string `json:"namespace"`
			Img       string `json:"img"`
			Version   string `json:"version"`
		} `json:"mesh-client"`
	} `json:"app"`
	Service struct {
		External struct {
			ExternalName string `json:"ExternalName"`
			Namespace    string `json:"Namespace"`
			ExternalHost string `json:"ExternalHost"`
			ExternalPort string `json:"ExternalPort"`
		} `json:"external"`
		Endpoints struct {
			ExternalName string `json:"ExternalName"`
			Namespace    string `json:"Namespace"`
			ExternalIp   string `json:"ExternalIp"`
			ExternalPort string `json:"ExternalPort"`
		} `json:"endpoints"`
	} `json:"service"`
}

const (
	configPath    = "/Users/admin/Documents/go-project/titan-template/local-project-demo/config-bus/operator-config.json"
	appBuildPath  = "/Users/admin/Documents/go-project/titan-template/local-project-demo/app/build.sh"
	externalPath  = "/Users/admin/Documents/go-project/titan-template/local-project-demo/external/external-service.sh"
	endpointsPath = "/Users/admin/Documents/go-project/titan-template/local-project-demo/external/endpoints-service.sh"
)

func initConfig(config string) (*operatorConfig, error) {
	jsonFile, err := os.Open(config)
	if err != nil {
		fmt.Println("error opening json file")
		return nil, err
	}
	jsonData, err := ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return nil, err
	}
	var post operatorConfig
	err = json.Unmarshal(jsonData, &post)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	fmt.Println(post)
	return &post, nil
}

func (receiver *DeployService) ApplyApp(config, app string) (string, error) {
	fmt.Println("applyApp")
	post, err := initConfig(config)
	if err != nil {
		return "", err
	}
	cmd := exec.Command(
		"bash",
		app,
		post.App.MeshClient.Img,
		post.App.MeshClient.Version,
		post.App.MeshClient.Namespace,
		post.App.MeshClient.AppCode,
		post.App.MeshClient.AppPort)
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	fmt.Println(string(out))
	return "success", nil
}

func (receiver *DeployService) ApplyExternal(config, external string) (string, error) {
	fmt.Println("applyExternal")
	post, err := initConfig(config)
	if err != nil {
		return "", err
	}
	cmd := exec.Command(
		"bash",
		external,
		post.Service.External.ExternalName,
		post.Service.External.Namespace,
		post.Service.External.ExternalHost,
		post.Service.External.ExternalPort)
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	fmt.Println(string(out))
	return "success", nil
}

func (receiver *DeployService) ApplyEndpoints(config, endpoints string) (string, error) {
	fmt.Println("applyEndpoints")
	post, err := initConfig(config)
	if err != nil {
		return "", err
	}
	cmd := exec.Command(
		"bash",
		endpoints,
		post.Service.Endpoints.ExternalName,
		post.Service.Endpoints.Namespace,
		post.Service.Endpoints.ExternalIp,
		post.Service.Endpoints.ExternalPort)
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	fmt.Println(string(out))
	return "success", nil
}
